/*
 * @Description: 01-控制最大请求数-任务数
 * @Author: dh
 * @Date: 2023-11-17 16:30:44
 * @LastEditors: dh
 * @LastEditTime: 2024-09-18 11:22:15
 */

function createTask(i) {
	return function () {
		return new Promise(resolve => {
			setTimeout(() => {
				resolve(i)
			}, 1000)
		})
	}
}

// TODO 基础班，拿不到返回结果
class TaskQueue {
	constructor() {
		this.max = 2
		this.taskList = []
		// setTimeout(() => {
		// 	this.run();
		// });
	}
	add(task) {
		this.taskList.push(task)
	}
	run() {
		if (!this.taskList.length) return
		const min = Math.min(this.max, this.taskList.length)
		for (let i = 0; i < min; i++) {
			this.max--
			const task = this.taskList.shift()
			task()
				.then(res => {
					console.log(res)
				})
				.finally(() => {
					this.max++
					this.run()
				})
		}
	}
}

const taskQueue = new TaskQueue()

for (let i = 0; i < 10; i++) {
	taskQueue.add(createTask(i))
}

taskQueue.run()

// TODO 升级版，能拿到返回结果
class TaskQueue2 {
	constructor() {
		this.max = 2
		this.taskList = []
	}
	add(task) {
		this.taskList.push(task)
	}
	run() {
		const https = this.taskList
		return new Promise((resolve, rej) => {
			const result = [] // 返回结果集
			let index = 0 // 当前执行任务的最大索引
			let count = 0 // 执行完成数量
			async function request() {
				if (index === https.length) return
				const i = index
				const http = https[index]
				index++
				http()
					.then(res => {
						result[i] = res
						// console.log(res);
					})
					.catch(err => {
						result[i] = err
					})
					.finally(() => {
						request()
						count++
						if (count === https.length) {
							resolve(result)
						}
					})
			}
			// 同时执行最多任务数
			const min = Math.min(this.max, https.length)
			for (let i = 0; i < min; i++) {
				request()
			}
		})
	}
}

const taskQueue2 = new TaskQueue2()

for (let i = 0; i < 10; i++) {
	taskQueue2.add(createTask(i))
}
taskQueue2.run().then(res => {
	console.log(res)
})
